package com.trf.member.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.trf.member.base.Page;
import com.trf.member.base.Result;
import com.trf.member.entity.Staff;
import com.trf.member.mapper.StaffMapper;
import com.trf.member.req.PasswordREQ;
import com.trf.member.req.StaffREQ;
import com.trf.member.service.IStaffService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.trf.member.util.JwtUtil;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 *  员工信息表 服务实现类
 * </p>
 *
 * @author 小小唐
 * @since 2023-03-04
 */
@Service
public class StaffServiceImpl extends ServiceImpl<StaffMapper, Staff> implements IStaffService {

    @Autowired
    JwtUtil jwtUtil;

    /**
     * 条件查询分页的方法实现
     * @param page 页码
     * @param size 每页记录数据
     * @param req  条件查询
     * @return
     */
    @Override
    public Result search(Long page, Long size, StaffREQ req) {
        //封装查询条件
        QueryWrapper<Staff> query = new QueryWrapper<>();
        if (req != null){
            if (StringUtils.isNotBlank(req.getName())){
                query.like("name",req.getName());
            }
            if (StringUtils.isNotBlank(req.getUsername())){
                query.like("username",req.getUsername());
            }
        }
        //封装分页对象
        IPage<Staff> p = new Page<>(page, size);
        IPage<Staff> data = baseMapper.selectPage(p,query);
        return Result.ok(data);
    }

    /**
     * 新增员工的方法实现
     * 1. 查询员工用户名是否存在，存在不允许新增
     * 2. 对密码进行加密保存
     * 3. 提交数据到 tb_staff 表
     * @param staff 员工详情
     * @return
     */
    @Override
    public Result add(Staff staff) {
        if (staff == null || StringUtils.isEmpty(staff.getUsername())){
            return Result.error("用户名不能为空");
        }
        //1、查询用户名是否存在
        Staff s = getByUsername(staff.getUsername());
        if (s != null){
            return Result.error("用户名已存在");
        }

        //2、使用SpringSecurity提供的加密器进行加密
        String password = new BCryptPasswordEncoder().encode(staff.getPassword());
        staff.setPassword(password);

        //3、保存在数据库
        boolean b = this.save(staff);
        if (b){
            return Result.ok();
        }
        return Result.error("新增失败");
    }

    /**
     * 更新员工的方法实现
     * @param id 员工id
     * @param staff 员工详情
     * @return
     */
    @Override
    public Result update(int id, Staff staff) {
        if (staff.getId() == null){
            staff.setId(id);
        }
        int size = baseMapper.updateById(staff);
        if (size < 1){
            return Result.error("修改员工信息失败");
        }
        return Result.ok();
    }

    /**
     * 校验原密码是否正确的实现方法
     * @param req 密码详情
     * @return
     */
    @Override
    public Result checkPassword(PasswordREQ req) {
        if (req == null || StringUtils.isEmpty(req.getPassword())){
            return Result.error("原密码不能为空");
        }
        Staff staff = baseMapper.selectById(req.getUserId());
        if (!new BCryptPasswordEncoder().matches(req.getPassword(),staff.getPassword())){
            return Result.error("原密码错误");
        }
        return Result.ok();
    }

    /**
     * 更新提交新密码
     * @param req 密码详情
     * @return
     */
    @Override
    public Result updatePassword(PasswordREQ req) {
        if (req == null ||StringUtils.isEmpty(req.getPassword())){
            return Result.error("新密码不能为空");
        }
        //更新密码
        Staff staff = baseMapper.selectById(req.getUserId());
        staff.setPassword(new BCryptPasswordEncoder().encode(req.getPassword()));
        baseMapper.updateById(staff);
        return Result.ok();
    }

    /**
     * 登录身份令牌
     * @param username 用户名
     * @param password 密码
     * @return
     */
    @Override
    public Result login(String username, String password) {
        Result error = Result.error("用户名或密码错误");

        if (StringUtils.isBlank(username) || StringUtils.isBlank(password)){
            return error;
        }

        // 1、通过用户名查询
        Staff staff = getByUsername(username);
        if (staff == null){
            return error;
        }

        // 2、存在，判断密码是否正确（输入的密码，数据库加密的密码）
        if (!new BCryptPasswordEncoder().matches(password,staff.getPassword())){
            return error;
        }

        // 3、生成token响应
        String jwt = jwtUtil.createJWT(staff.getId() + "", staff.getUsername(), true);
        // 手动封装个json对象{token: jwt}
        Map<String, String> map = new HashMap<>();
        map.put("token",jwt);
        return Result.ok(map);
    }

    /**
     * 登录成功后，通过 token 来获取用户信息
     * @param token 身份令牌
     * @return
     */
    @Override
    public Result getUserInfo(String token) {
        //解析jwt
        Claims claims = jwtUtil.parseJWT(token);
        if (claims == null || StringUtils.isBlank(claims.getSubject())){
            return Result.error("获取用户信息失败");
        }
        //获取用户名
        String username = claims.getSubject();
        // 1、通过用户名查询
        Staff staff = getByUsername(username);
        if (staff == null){
            return Result.error("用户不存在");
        }
        // 2、将密码设置为null，不响应给前端
        staff.setPassword(null);
        return Result.ok(staff);
    }

    /**
     * 私有化方法
     * @param username 账号
     * @return
     */
    private Staff getByUsername(String username) {
        QueryWrapper<Staff> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username",username);
        return baseMapper.selectOne(queryWrapper);
    }
}
